### Copyright (C) 2009 Kelvin Ho <kelvin.ho.ka.wai@gmail.com>
###
### This library is free software; you can redistribute it and/or
### modify it under the terms of the GNU General Public License as
### published by the Free Software Foundation; either version 2 of the
### License, or (at your option) any later version.
###
### This library is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
### General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with this library; if not, write to the Free Software
### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
### 02111-1307, USA.
import inspect

D_ERROR = (0, 'E', 'Error')
D_WARN = (1, 'W', 'Warn')
D_INFO = (2, 'I', 'Info')
D_DEBUG = (3, 'D', 'Debug')

D = {
  'd_level': D_INFO,
  'show_level': True,
  'show_fn': False,
  'show_ln': False,
  'show_func': True
}
 
def set_debug_level(s):
  for DD in [D_ERROR, D_WARN, D_INFO, D_DEBUG]:
    if DD[1] == s:
      print 'Setting debug level to %s' % DD[2]
      D['d_level'] = DD

def is_higher(l1, l2):
  return l1[0] < l2[0]

def is_lower(l1, l2):
  return l1[0] > l2[0]

def equal(l1, l2):
  return l1[0] == l2[0]

def debug(s, level=D_DEBUG):
  if not is_lower(level, D['d_level']):
    frame = get_frame_of_debug_caller()
    fn, ln_num, func = frame[1], frame[2], frame[3]
    fn_el = fn.split('/')
    level_s = level[1] if D['show_level'] else ''
    fn = '%s' % fn_el[len(fn_el) - 1] if D['show_fn'] else ''
    ln = '%d' % ln_num if D['show_ln'] else ''
    func = '%s()' % func if D['show_func'] else ''
    pre_list = [pre for pre in [level_s, fn, ln, func] if pre]
    preamble = '[%s] ' % ':'.join(pre_list) if pre_list else ''
    print '%s%s' % (preamble, s)

def info(s):
  debug(s, level=D_INFO)

def warn(s):
  debug(s, level=D_WARN)

def error(s):
  debug(s, level=D_ERROR)

def get_frame_of_debug_caller():
  f = inspect.stack()
  for ff in f:
    #print ff[0]
    if ff[1].find('ebug') == -1:
      return ff
  return None

if __name__ == "__main__":
  get_frame_of_debug_caller()
